use std::io::Result;

trait Sender {
    fn send(&self, data: &str) -> Result<()>;
}

#[derive(Debug)]
struct HttpSender {
    name:String,
}

impl HttpSender {
    fn new(name: &str) -> Self {
        Self {
            name: name.to_owned(),
        }
    }
}
impl Sender for HttpSender {
    fn send(&self, data: &str) -> Result<()> {
        println!("send: from [HttpSender]: {data}");
        Ok(())
    }
}


#[derive(Debug)]
struct SslSender<S> 
where S: Sender
{
    name: String,
    //TODO: 
    sender: S,
}
impl<S> SslSender<S> 
where S: Sender
{
    fn new(name: &str, sender: S) -> Self {
        Self {
            name: name.to_owned(),
            sender
        }
    }
}
impl<S> Sender for SslSender<S> 
where S: Sender
{
    fn send(&self, data: &str) -> Result<()> {
        println!("send: from [SslSender] send: {data}");
        self.sender.send(data)?;
        Ok(())
    }
}


#[cfg(test)]
mod test {
    use super::*;
    #[test]
    fn test() -> std::io::Result<()>{
        let sender = HttpSender::new("http sender");
        sender.send("hello world")?;

        let sender = SslSender::new("safe", HttpSender::new("http") );
        sender.send("world 's best")
    }
}

